import { PropType, computed, defineComponent, provide, reactive, watch } from "vue";
import { TabProps } from "./Tab";
import { FeatherChevronLeft, FeatherChevronRight, FeatherX } from "cui-vue-icons/feather";

export * from './Tab';

export interface TabsProps {
    card?: boolean,
    activeName?: string,
    extra?: any,
    onTabClick?: Function,
    onRemove?: Function,
    duration?: number
}

type TabStore = {
    activeName: string,
    tabs: TabProps[],
    scroll: boolean,
    scrollLeft: number
}

export default defineComponent({
    name: "Tabs",
    props: {
        card: {type: Boolean as PropType<TabsProps['card']>},
        activeName: {type: String as PropType<TabsProps['activeName']>},
        extra: {type: Object as PropType<TabsProps['extra']>},
        duration: {type: Number as PropType<TabsProps['duration']>}
    },
    emits: ['tabClick', 'remove'],
    setup (props: TabsProps, { emit, slots, expose }) {
        let line: any;
        let scroll: any;
        let header: any;
        const classList = computed(() => ({
            'cm-tabs': true,
            'cm-tabs-card': props.card,
            'cm-tabs-overflow': store.scroll
        }));

        const store = reactive({
            activeName: props.activeName ?? '',
            tabs: [],
            scroll: false,
            scrollLeft: 0
        } as TabStore);

        // 往前滚动
        const scrollPrev = () => {
            const scrollWidth = scroll.getBoundingClientRect().width;
            let scrollLeft = store.scrollLeft + scrollWidth;
            scrollLeft = Math.min(0, scrollLeft);
            header.style.transform = `translate(${scrollLeft}px, 0)`;
            store.scrollLeft = scrollLeft;
        };

        // 往后滚动
        const scrollNext = () => {
            const scrollWidth = scroll.getBoundingClientRect().width;
            const headerWidth = header.getBoundingClientRect().width;
            let scrollLeft = store.scrollLeft - scrollWidth;
            const maxLeft = scrollWidth - headerWidth;
            scrollLeft = Math.max(maxLeft, scrollLeft);
            header.style.transform = `translate(${scrollLeft}px, 0)`;
            store.scrollLeft = scrollLeft;
        };

        const addTab = (obj: TabProps) => {
            store.tabs.push(obj);
            setTimeout(() => {
                updateScroll();
            });
        };

        const onTabClick = (item: TabProps) => {
            store.activeName = item.name;
            console.log(item.name, store.activeName);

            emit('tabClick', item);
        };

        /**
         * 删除tab
         * @param name
         * @param e
         */
        const onRemove = (name: string, e: any) => {
            e.preventDefault && e.preventDefault();
            e.stopPropagation && e.stopPropagation();
            const newArr: TabProps[] = store.tabs.filter((tab: TabProps) => {
                return tab.name !== name;
            });
            if (store.activeName === name) {
                store.activeName = newArr[newArr.length - 1].name;
            }
            store.tabs = newArr;
            emit('remove', name);
            updateScroll();
        };

        /**
         * 内容滚动样式
         * @returns
         */
        const contextStyle = () => {
            const avtiveName = store.activeName;
            let currentIndex: number = 0;
            store.tabs.forEach((atab: any, index: number) => {
                if (atab.name === avtiveName) {
                    currentIndex = index;
                }
            });

            const s: any = {
                'transform': `translate(${-currentIndex * 100}%, 0)`
            };

            if (props.duration !== undefined && typeof props.duration === 'number') {
                s['transition-duration'] = props.duration + 'ms';
            }

            return s;
        };

        watch(() => props.activeName, (name) => {
            store.activeName = name;
        });

        // onMount (() => {
        //     updateScroll();
        // });

        const updateScroll = () => {
            const scrollWidth = scroll.getBoundingClientRect().width;
            const headerWidth = header.getBoundingClientRect().width;
            if (headerWidth > scrollWidth && !store.scroll) {
                store.scroll = true;

            }
            if (headerWidth < scrollWidth && store.scroll) {
                store.scroll = false;
                scrollPrev();
            }
        };

        // 更新下线的移动位置
        const lineStyle = () => {
            const avtiveName = store.activeName;
            if (!props.card && header) {
                let currentIndex: number = 0;
                store.tabs.forEach((atab: any, index: number) => {
                    if (atab.name === avtiveName) {
                        currentIndex = index;
                    }
                });

                const eles = header.querySelectorAll('.cm-tabs-header-item');
                const ele = eles[currentIndex];
                if (!ele) {
                    return;
                }
                const wrap = header.closest('.cm-tabs-header-wrap');
                const close = ele.querySelector('.cm-tabs-close');
                const closeW = close ? close.getBoundingClientRect().width : 0;

                const rect = ele.getBoundingClientRect();
                const wrapRect = wrap.getBoundingClientRect();
                const headerLeft = rect.left - wrapRect.left;
                const width = rect.width - closeW;
                line.style.width = `${width}px`;
                line.style.left = `${headerLeft}px`;
                return {
                    width: `${width}px`,
                    left: `${headerLeft}px`
                };
            }
        };

        expose({
            addTab
        });


        provide('CMTabsContext', {
            addTab,
            store
        });

        return () => <div class={classList.value}>
            <div class="cm-tabs-header-wrap">
                <div class="cm-tabs-active-line" ref={(el) => line = el} style={lineStyle()}></div>
                <div class="cm-tabs-scroll" ref={(el) => scroll = el}>
                    <ul class="cm-tabs-header" ref={(el) => header = el}>
                        {
                            store.tabs.map(item => {
                                const className = () => ({
                                    'cm-tabs-header-item': true,
                                    'cm-tabs-header-item-active': item.name === store.activeName,
                                    'cm-tabs-header-item-disabled': item.disabled
                                });
                                return <li class={className()}
                                    onClick={onTabClick.bind(null, item)}>
                                    {item.icon}
                                    {item.title}
                                    {
                                        item.closeable
                                            ? <FeatherX onClick={onRemove.bind(null, item.name)} class="cm-tabs-close" size={12}/>
                                            : null
                                    }
                                </li>;
                            })
                        }
                    </ul>
                </div>
                {
                    props.extra ? props.extra : null
                }
                <div class="cm-tabs-prev" onClick={scrollPrev}>
                    <FeatherChevronLeft size={14}/>
                </div>
                <div class="cm-tabs-next" onClick={scrollNext}>
                    <FeatherChevronRight size={14}/>
                </div>
            </div>
            <div class="cm-tabs-content" style={contextStyle()}>
                {
                    slots.default?.()
                }
            </div>
        </div>;
    }
});
